import axios from 'axios'
import lodash, { assign, cloneDeep } from 'lodash'
import { Paged } from './Paged'
import { safe } from '.'
import { OrderModel } from '~/model/OrderModel'
import { OrderSerializer } from '~/serializer/OrderSerializer'

export interface OrderFilterBatch {
  material?: string
  consumer?: string
  invalid?: string
  settled?: string
  date_start?: string
  date_end?: string
  search?: string
}

// 订单相关接口
export abstract class OrderApi {
  private static quering?: Promise<OrderModel[]>
  private static cache?: OrderModel[]
  private static clearCache() {
    delete this.quering
    delete this.cache
  }

  // public static async getAllRaw(): Promise<any[]> {

  // }

  public static async getAll(): Promise<OrderModel[]> {
    // use cache
    if (this.cache) {
      return cloneDeep(this.cache)
    }

    // pend
    if (this.quering) {
      return await this.quering
    }

    const inner: () => Promise<OrderModel[]> = async () => {
      const res = await axios.get('orders/get_all/')
      const arr: any[] = res.data
      const ret = await Promise.all(
        arr.map(x => OrderSerializer.deserialize(x)),
      )
      this.cache = ret
      return ret
    }

    this.quering = inner()
    return await this.quering
  }

  public static async getToday(): Promise<OrderModel[]> {
    const res = await axios.get('orders/get_today/')
    const arr: any[] = res.data
    const ret = await Promise.all(
      arr.map(x => OrderSerializer.deserialize(x)),
    )
    return ret
  }

  public static async getPaged(page_num = 1, per_page = 20, filterBatch?: OrderFilterBatch): Promise<Paged<OrderModel>> {
    console.log('filterBatch');
    console.log(filterBatch);
    
    let url = `orders/get_paged/?per_page=${per_page}&page_num=${page_num}`

    // 添加过滤器
    if (filterBatch) {
      // material?: number
      if (filterBatch.material) {
        url += `&material=${filterBatch.material}`
      }
      // consumer?: number
      if (filterBatch.consumer) {
        url += `&consumer=${filterBatch.consumer}`
      }
      // invalid?: boolean
      if (filterBatch.invalid) {
        url += `&invalid=${filterBatch.invalid}`
      }
      // settled?: boolean
      if (filterBatch.settled) {
        url += `&settled=${filterBatch.settled}`
      }
      // date_start?: Date
      if (filterBatch.date_start) {
        url += `&date_start=${filterBatch.date_start}`
      }
      // date_end?: Date
      if (filterBatch.date_end) {
        url += `&date_end=${filterBatch.date_end}`
      }
      // search?: Date
      if (filterBatch.search) {
        url += `&search=${encodeURIComponent(filterBatch.search)}`
      }
    }

    const res = await axios.get(url)

    const arr: Paged<any> = res.data
    arr.objects = await Promise.all(
      arr.objects.map(x => OrderSerializer.deserialize(x)),
    )
    return arr
  }

  public static async get(id: number): Promise<OrderModel> {
    // use cache
    if (this.cache) {
      const _res = this.cache.find(x => x.id === id)
      if (_res) {
        return lodash.cloneDeep(_res)
      }
      else {
        console.error(`this.cache, 没有id=${id}`)
        console.error(this.cache)
      }
    }

    const res = await axios.get(`orders/${id}/get/`)
    // console.log(res)
    const ret = await OrderSerializer.deserialize(res.data)
    return ret
  }

  public static async add(order: OrderModel) {
    this.clearCache()
    return safe(() => axios.post(
      'orders/',
      OrderSerializer.serialize(order),
    ))
  }

  public static async update(id: number, order: OrderModel): Promise<boolean> {
    this.clearCache()
    return safe(() => axios.put(
      `orders/${id}/`,
      OrderSerializer.serialize(order),
    ))
  }

  public static async invalidate(id: number): Promise<boolean> {
    this.clearCache()
    return safe(() => axios.put(
      `orders/${id}/invalidate/`,
    ))
  }

  public static async settle(id: number): Promise<boolean> {
    this.clearCache()
    return safe(() => axios.put(
      `orders/${id}/settle/`,
    ))
  }

  public static async getNewOrderBatchOfConsumer(ConsumerId: number): Promise<number> {
    const res = await axios.get(`orders/${ConsumerId}/get_batch/`)
    const ret = await res.data
    return Number.parseInt(ret)
  }

  public static async uploadStub(id: number, image: Blob) {
    const fd = new FormData()
    fd.append('stub', image)

    this.clearCache()
    return safe(() => axios.post(
      `orders/${id}/upload_stub/`,
      fd,
    ))
  }

  public static async settleBatch(ids: number[]): Promise<boolean> {
    this.clearCache()
    return safe(() => axios.put(
      'orders/settle_batch/',
      ids,
    ))
  }

  public static async print(id: number, showPrice = true): Promise<boolean> {
    // router.push(`/orders/print?id=${id}`)
    const printServiceUrl = 'http://10.0.0.4:8080/'
    const printPageUrl = 'http://10.0.0.2/'
    try {
      const res = await fetch(
        `${printServiceUrl}${printPageUrl}orders/print?id=${id}&showPrice=${showPrice ? 1 : 0}`,
        {
          method: 'post',
        },
      )
      return res.ok
    }
    catch {
      return false
    }
  }

  public static async getForPrint(id: number): Promise<OrderModel> {
    const res = await axios.get(`public_orders/${id}/get_for_print/`)
    const ret = assign(new OrderModel(), res.data)
    return ret
  }
}
